home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Updaters
/
WhiteCap 3.0.4
/
WhiteCap Source.sit
/
WhiteCap Source
/
Common
/
General Tools
/
XList.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-07-13
|
4KB
|
209 lines
#include "XList.h"
XList::XList( nodeClass* inParent ) :
nodeClass( inParent ) {
mCachedNode = NULL;
}
void XList::UpdateCounts( int inShallowChange ) {
nodeClass::UpdateCounts( inShallowChange );
mCachedNode = NULL;
}
nodeClass* XList::findSubNode( long inNum ) {
nodeClass* retPtr = NULL;
long i;
if ( mCachedNode ) { // Check cached node...
i = inNum - mCachedNodeNum; // See how far away our cached node is
if ( i > -4 && i < 4 ) {
retPtr = mCachedNode;
if ( i < 0 ) { // The cached node was after the desired
for ( ; i != 0 && retPtr; i++ ) // Move forward the num that the cache is off
retPtr = retPtr -> PrevInChain( this ); }
else {
for ( ; i != 0 && retPtr; i-- )
retPtr = retPtr -> NextInChain( this );
}
}
#ifdef EG_DEBUG
if ( retPtr )
sCacheHitsA++;
sCacheTrysA++;
#endif
}
if ( ! retPtr ) // If no cache his was found
retPtr = nodeClass::findSubNode( inNum ); // Do it by brute force
if ( retPtr ) {
mCachedNodeNum = inNum;
mCachedNode = retPtr;
}
return retPtr;
}
long XList::findSubNode( nodeClass* inNodePtr ) {
nodeClass* nodePtr;
long n = 0;
if ( mCachedNode && inNodePtr ) { // If we have a cache available
if ( mCachedNode == inNodePtr ) // Check trivial cache case
n = mCachedNodeNum;
if ( n == 0 ) { // If no hit yet...
nodePtr = mCachedNode -> NextInChain( this );
if ( nodePtr == inNodePtr ) // Check node after cached node
n = mCachedNodeNum + 1;
}
if ( n == 0 ) { // If no hit yet...
nodePtr = mCachedNode -> PrevInChain( this );
if ( nodePtr == inNodePtr ) // Check node before cached node
n = mCachedNodeNum - 1;
}
#ifdef EG_DEBUG
if ( n > 0 )
sCacheHitsB++;
sCacheTrysB++;
#endif
}
if ( n == 0 ) // If no cache hit...
n = nodeClass::findSubNode( inNodePtr ); // Do it with brute force.
if ( n > 0 ) { // Update the cache if possible...
mCachedNode = inNodePtr;
mCachedNodeNum = n;
}
return n;
}
long XList::GetParent( long inCellNum ) {
nodeClass* nodePtr = findSubNode( inCellNum );
if ( nodePtr ) {
if ( nodePtr -> GetParent() == this )
return 0;
else
return findSubNode( nodePtr -> GetParent() ); }
else
return -1;
}
XLongList* XList::ManageClick( long inCell, bool inShift, bool inCmd, bool inDeselectRest ) {
XLongList* retPtr = ListSocket::ManageClick( inCell, inShift, inCmd, inDeselectRest );
nodeClass* nodePtr = GetDeepTail();
long i = deepCount();
while ( nodePtr ) {
if ( nodePtr -> IsSelected() ) {
SetInsertionPt( i, nodePtr -> CountDepth( this ) - 1 );
return retPtr;
}
i--;
nodePtr = nodePtr -> PrevInChain( this );
}
return retPtr;
}
void XList::DoBestInsert( nodeClass* inNodeToAdd ) {
nodeClass* insertPt = findSubNode( mInsertionPt );
long insDepth;
if ( inNodeToAdd ) {
if ( insertPt ) {
insDepth = insertPt -> CountDepth( this ) - 1;
while ( insDepth > mInsertionDepth && insertPt ) {
insertPt = insertPt -> GetParent();
insDepth--;
if ( insertPt == this )
insertPt = NULL;
}
}
if ( insertPt ) {
if ( insDepth == mInsertionDepth )
inNodeToAdd -> insertAfter( insertPt );
else // depth < inDepth
insertPt -> addToHead( inNodeToAdd ); }
else {
if ( mInsertionPt <= 0 )
addToHead( inNodeToAdd );
else
addToTail( inNodeToAdd );
}
mInsertionPt = findSubNode( inNodeToAdd );
mInsertionDepth = inNodeToAdd -> CountDepth( this ) - 1;
}
}
void XList::SetInsertPtBefore( nodeClass* inInsertPt ) {
long n = findSubNode( inInsertPt );
if ( n <= 0 )
inInsertPt = GetDeepTail();
else if ( n == 1 )
inInsertPt = NULL;
else
inInsertPt = inInsertPt -> PrevInChain( this );
if ( inInsertPt )
SetInsertionPt( findSubNode( inInsertPt ), inInsertPt -> CountDepth( this ) - 1 );
else
SetInsertionPt( 0, 0 );
}
void XList::SetSelected( long inElementNum, bool isSelected ) {
nodeClass* nodePtr = findSubNode( inElementNum );
if ( nodePtr )
nodePtr -> SetSelected( isSelected );
}
bool XList::IsSelected( long inElementNum ) {
nodeClass* nodePtr = findSubNode( inElementNum );
if ( nodePtr )
return nodePtr -> IsSelected();
else
return false;
}
long XList::NumCells() {
return deepCount();
}